package com.ciei.dpagm.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.ciei.dpagm.common.converter.JsonConverter;
import com.ciei.dpagm.common.enums.ChipTypeEnum;
import com.ciei.dpagm.common.enums.ErrorCodeEnum;
import com.ciei.dpagm.entity.*;
import com.ciei.dpagm.util.APP;
import com.ciei.dpagm.util.FileUtils;
import com.ciei.dpagm.util.JsonUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author pp
 * @date 2023/06/06
 */
@Service
public class MainEngineeringService {

    private static final Logger LOGGER = LoggerFactory.getLogger(MainEngineeringService.class);

    @Value("${baseFilePath}")
    private String baseFilePath;

    @Autowired
    private ProjectService projectService;

    @Autowired
    private ChipService chipService;

    @Autowired
    private DriverLibraryService driverLibraryService;

    @Autowired
    private ChipControlModeService chipControlModeService;

    @Autowired
    private ChipControlModeInterfaceService chipControlModeInterfaceService;

    @Autowired
    private ProjectSlaveChipConfigService projectSlaveChipConfigService;

    @Autowired
    private ProjectSlaveChipConfigInterfaceService projectSlaveChipConfigInterfaceService;

    @Autowired
    private ChipControlModeInterfaceTypeService chipControlModeInterfaceTypeService;

    @Autowired
    private ChipInterfaceService chipInterfaceService;

    @Autowired
    private CircuitGenerationModuleChipService circuitModuleNameMappingService;

    @Autowired
    private ChipPinService chipPinService;

    private final String chipLayoutJsonTemplatePath = "templates/芯片布局json模板.json";


    /**
     * 新增项目
     * @param data
     * @return
     */
    public JSONObject addProject(JSONObject data){
        LOGGER.info("主程序-创建项目-原始数据:" + data.toJSONString());
        Integer mainUserId = data.getInteger("mainUserId");
        Integer mainEngineeringId = data.getInteger("mainEngineeringId");
        String projectName = data.getString("projectName");
        String projectDescription = data.getString("projectDescription");
        if(mainUserId == null){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"mainUserId不能为空");
        }
        if(mainEngineeringId == null){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"mainEngineeringId不能为空");
        }
        Project project = new Project();
        if(StringUtils.isBlank(projectName)){
            projectName = "驱动程序适配";
        }
        project.setName(projectName);
        if(StringUtils.isNotBlank(projectDescription)){
            project.setDescription(projectDescription);
        }
        project.setCreatorId(mainUserId);
        project.setUpdateTime(new Date());
        project.setUpdateUserId(mainUserId);
        project.setMainEngineeringId(mainEngineeringId);
        projectService.save(project);
        if(data.getJSONObject("layoutContent")!=null) {
            try {
                JSONObject layoutContentData = data.getJSONObject("layoutContent");
                JSONArray nodes = layoutContentData.getJSONArray("nodes");
                String messageTitle = "主程序-创建项目-芯片布局：";
                Chip masterChip = null;
                List<Chip> slaveChipList = new ArrayList<>();
                String masterChipCode = "";
                List<String> slaveChipCodeList = new ArrayList<>();
                Boolean isSupportCreateLayout = true;
                for (int i = 0; i < nodes.size(); i++) {
                    JSONObject nodeData = nodes.getJSONObject(i);
                    String chipCode = nodeData.getString("chipCode");
                    String model = nodeData.getString("model");
                    Map<SFunction<Chip, ?>, Object> fieldValueMap = new HashMap<>();
                    fieldValueMap.put(Chip::getModel,model);
                    if(nodeData.getString("manufacturer") != null){
                        String manufacturer = nodeData.getString("manufacturer");
                        fieldValueMap.put(Chip::getManufacturer,manufacturer);
                    }
                    List<Chip> chipList = chipService.findByProperties(fieldValueMap);
                    if(chipList.isEmpty()){
                        // 若从芯片表中找不到芯片数据，尝试从映射中找芯片数据
                        List<Integer> chipIdList=StringUtils.isNotBlank(nodeData.getString("model"))?
                                circuitModuleNameMappingService.findByProperty(CircuitGenerationModuleChip::getModel,nodeData.getString("model"))
                                        .stream().map(CircuitGenerationModuleChip::getChipId).collect(Collectors.toList()):
                                new ArrayList<>();
                        List<Chip> chipListByModel = chipService.findListByIds(chipIdList);
                        if (chipListByModel.isEmpty()){
                            LOGGER.info(messageTitle + "找不到芯片数据，节点数据内容为:" + nodeData.toJSONString());
//                            isSupportCreateLayout = false;
                        }
                        // 若从映射表中找到芯片数据，将映射表中的芯片数据赋值给chipList
                        chipList = chipListByModel;
                    }
                    if(chipList.size() > 1){
                        String manufacturer = nodeData.getString("manufacturer");
                        // 若芯片表中找到多个芯片数据，尝试通过芯片厂商过滤芯片数据
                        if(StringUtils.isNotBlank(manufacturer)){
                            List<Chip> chipListByManufacturer = chipList.stream().filter(c -> manufacturer.equals(c.getManufacturer())).collect(Collectors.toList());
                            if(chipListByManufacturer.size() == 1){
                                chipList = chipListByManufacturer;
                            }else {
                                LOGGER.info(messageTitle + "找到多个芯片，无法确认应使用哪个芯片数据，节点数据内容为:" + nodeData.toJSONString());
                                isSupportCreateLayout = false;
                            }
                        }else {
                            LOGGER.info(messageTitle + "找到多个芯片，无法确认应使用哪个芯片数据，节点数据内容为:" + nodeData.toJSONString());
                            isSupportCreateLayout = false;
                        }
                    }
                    Chip chip = chipList.isEmpty()?new Chip():chipList.get(0);
                    if(ChipTypeEnum.MASTER.getType().equals(chip.getType())){
                        if(masterChip == null){
                            masterChip = chip;
                            masterChipCode = chipCode;
                        }else{
                            LOGGER.info(messageTitle + "暂不支持多个主控芯片，节点列表数据内容为:" + nodes.toJSONString());
                            isSupportCreateLayout = false;
                        }
                    }else if(ChipTypeEnum.SLAVE.getType().equals(chip.getType())) {
                        slaveChipList.add(chip);
                        slaveChipCodeList.add(chipCode);
                    }
                }
                if( masterChip == null || slaveChipList.isEmpty()){
                    isSupportCreateLayout = false;
                }
                JSONArray edges = layoutContentData.getJSONArray("edges");
                String chipLayoutJsonStr = FileUtils.getStrByTemplatePath(chipLayoutJsonTemplatePath);
                JSONObject chipLayoutJson = JSONObject.parseObject(chipLayoutJsonStr);
                JSONObject contentData = chipLayoutJson.getJSONObject("content");
                JSONArray templateNodes = contentData.getJSONArray("nodes");
                JSONObject masterNode = templateNodes.getJSONObject(0);
                JSONObject masterNodeData = masterNode.getJSONObject("data");
                String masterChipUuid = UUID.randomUUID().toString();
                String masterDisplayName = masterChip.getDisplayName() == null ? "" : masterChip.getDisplayName();
                masterNodeData.fluentPut("chipId", masterChip.getChipId())
                        .fluentPut("chipType", masterChip.getType())
                        .fluentPut("masterChipId", masterChip.getChipId())
                        .fluentPut("displayName", masterDisplayName)
                        .fluentPut("displayCategory", masterChip.getDisplayCategory());
                masterNode.fluentPut("id", masterChipUuid)
                        .fluentPut("label", masterDisplayName)
                        .fluentPut("content", masterDisplayName)
                        .fluentPut("data", masterNodeData);
                // 用于判断已创建连线下标，只有连线两端的节点都存在时，才生成连线数据，若连线数据指向的节点不存在，该连线不生成。注:节点暂不影响
                int createEdgeIndex = 0;
                for (int edgeIndex = 0; edgeIndex < edges.size(); edgeIndex++) {
                    JSONObject edgeData = edges.getJSONObject(edgeIndex);
                    // 电路生成模块可能不考虑芯片自动生成时，源、目标的布局，默认处理成源为主控芯片、目标为被控芯片
                    String sourceChipCode = edgeData.getString("sourceChipCode");
                    String targetChipCode = edgeData.getString("targetChipCode");
                    String slaveChipCode;
                    if(masterChipCode.equals(sourceChipCode) && slaveChipCodeList.contains(targetChipCode) ){
                        slaveChipCode = targetChipCode;
                    }else if(masterChipCode.equals(targetChipCode) && slaveChipCodeList.contains(sourceChipCode)){
                        slaveChipCode = sourceChipCode;
                    }else{
                        continue;
                    }
                    Chip slaveChip = new Chip();
                    for (int j = 0; j < slaveChipCodeList.size(); j++) {
                        if(slaveChipCodeList.get(j).equals(slaveChipCode)){
                            slaveChip = slaveChipList.get(j);
                        }
                    }
                    JSONObject configData = edgeData.getJSONObject("data").getJSONObject("configData");
                    if(createEdgeIndex > 0){
                        JSONArray templateEdges = contentData.getJSONArray("edges");
                        JSONObject templateZeroEdge = templateEdges.getJSONObject(0);
                        templateEdges.add(JSONObject.parseObject(JSONObject.toJSONString(templateZeroEdge)));
                    }
                    if(edgeIndex > 0){
                        JSONObject slaveOneNode = templateNodes.getJSONObject(1);
                        JSONObject slaveNode = JSONObject.parseObject(JSONObject.toJSONString(slaveOneNode));
                        slaveNode.fluentPut("y",slaveOneNode.getInteger("y") + (edgeIndex * 200));
                        templateNodes.add(slaveNode);
                    }
                    JSONObject templateEdge = contentData.getJSONArray("edges").getJSONObject(createEdgeIndex);
                    JSONObject templateEdgeData = templateEdge.getJSONObject("data");
                    JSONObject adaptiveDriverLibraryData = new JSONObject();
                    adaptiveDriverLibraryData.fluentPut("masterChipId",masterChip.getChipId())
                            .fluentPut("slaveChipId",slaveChip.getChipId());
                    JSONObject adaptiveDriverLibraryJson = driverLibraryService.adaptiveDriverLibrary(adaptiveDriverLibraryData);
                    if(adaptiveDriverLibraryJson.getBoolean(APP.SUCCESS)){
                        Integer driverLibraryId = adaptiveDriverLibraryJson.getInteger(APP.DATA);
                        templateEdgeData.fluentPut("masterChipId",masterChip.getChipId())
                                .fluentPut("slaveChipId",slaveChip.getChipId())
                                .fluentPut("driverLibraryId",driverLibraryId);
                        String edgeUuid  =  UUID.randomUUID().toString();
                        String slaveChipUuid  =  UUID.randomUUID().toString();
                        templateEdge.fluentPut("id",edgeUuid)
                                .fluentPut("source",masterChipUuid)
                                .fluentPut("target",slaveChipUuid)
                                .fluentPut("masterChipNodeId",masterChipUuid)
                                .fluentPut("slaveChipNodeId",slaveChipUuid);
                        JSONObject slaveNode = templateNodes.getJSONObject(edgeIndex + 1);
                        JSONObject slaveNodeData = slaveNode.getJSONObject("data");
                        String slaveDisplayName = slaveChip.getDisplayName() == null ? "" : slaveChip.getDisplayName();
                        slaveNodeData.fluentPut("chipId",slaveChip.getChipId())
                                .fluentPut("chipType",slaveChip.getType())
                                .fluentPut("displayName", slaveDisplayName)
                                .fluentPut("displayCategory",slaveChip.getDisplayCategory());
                        slaveNode.fluentPut("id",slaveChipUuid)
                                .fluentPut("label",slaveDisplayName)
                                .fluentPut("content",slaveDisplayName)
                                .fluentPut("data",slaveNodeData);

                        // 将configData转换为所需信息(控制模式和接口列表)
                        List<ChipInterface> chipInterfaceList = chipInterfaceService.findByProperty(ChipInterface::getChipId,masterChip.getChipId());
                        String controlModeInterfaceName = getControlModeTypeFromInterfaceList(configData.getJSONObject("peripheralData").getString("masterChipPeripheralName"),chipInterfaceList);
                        if(StringUtils.isNotBlank(controlModeInterfaceName)) {
                            JSONObject projectSlaveChipConfigInfo = convertToInterfaceListAndControlMode(controlModeInterfaceName, chipInterfaceList, configData.getJSONArray("pinList"), driverLibraryId, slaveChip.getChipId(), masterChip);
                            if(!projectSlaveChipConfigInfo.isEmpty()){
                                ChipControlMode chipControlModeResult = projectSlaveChipConfigInfo.getObject("chipControlModeResult",ChipControlMode.class);
                                ProjectSlaveChipConfig projectSlaveChipConfig = new ProjectSlaveChipConfig();
                                projectSlaveChipConfig.setChipId(slaveChip.getChipId());
                                projectSlaveChipConfig.setProjectId(project.getProjectId());
                                projectSlaveChipConfig.setComponentId(edgeUuid);
                                projectSlaveChipConfig.setDriverLibraryId(driverLibraryId);
                                if (chipControlModeResult == null) {
                                    LOGGER.error(messageTitle + "找不到控制模式数据，请检查外设接口是否正确,目标连接信息为:" + edgeData.toJSONString());
                                    isSupportCreateLayout = false;
                                }else {
                                    projectSlaveChipConfig.setControlModeId(chipControlModeResult.getControlModeId());
                                    projectSlaveChipConfig.setControlModeName(chipControlModeResult.getName());
                                    projectSlaveChipConfig.setCreatorId(mainUserId);
                                    projectSlaveChipConfigService.save(projectSlaveChipConfig);
                                    List<ProjectSlaveChipConfigInterface> addProjectSlaveChipConfigInterfaceList = (List<ProjectSlaveChipConfigInterface>) projectSlaveChipConfigInfo.getOrDefault("addProjectSlaveChipConfigInterfaceList",new ArrayList<ProjectSlaveChipConfigInterface>());
                                    if(!addProjectSlaveChipConfigInterfaceList.isEmpty()){
                                        // 赋值createUserId、projectSlaveChipConfigId
                                        for (ProjectSlaveChipConfigInterface projectSlaveChipConfigInterface : addProjectSlaveChipConfigInterfaceList) {
                                            projectSlaveChipConfigInterface.setProjectSlaveChipConfigId(projectSlaveChipConfig.getProjectSlaveChipConfigId());
                                            projectSlaveChipConfigInterface.setCreatorId(mainUserId);
                                        }
                                        projectSlaveChipConfigInterfaceService.insertBatchSomeColumn(addProjectSlaveChipConfigInterfaceList);
                                    }
                                }
                            }
                        }else {
                            LOGGER.error(messageTitle + "找不到控制模式类型名称，请检查外设接口是否正确,目标连接信息为:" + edgeData.toJSONString());
                        }
                    }else{
                        LOGGER.info(messageTitle + adaptiveDriverLibraryJson.getString(APP.MESSAGE));
                        isSupportCreateLayout = false;
                    }
                    createEdgeIndex++;
                }

                if(isSupportCreateLayout){
                    project.setLayoutContent(chipLayoutJson.toJSONString());
                }

            }catch (Exception e){
                LOGGER.error("自动生成布局文件失败，数据内容为:" + data.toJSONString() + "，异常内容为:" + e.getMessage()+e);
                e.printStackTrace();
            }
            projectService.updateById(project);
        }
        LOGGER.info("主程序-创建项目-存储数据:" + JSONObject.toJSONString(project));
        return JsonUtil.getSuccess("新增成功").fluentPut(APP.DATA,packageInitData(project));
    }

    /**
     * 基于接口列表获取控制模式数据
     * @param configMasterChipPeripheralName 配置数据中的主控芯片外设名称
     * @param chipInterfaceList 芯片接口列表
     * @return
     */
    private String getControlModeTypeFromInterfaceList(String configMasterChipPeripheralName,List<ChipInterface> chipInterfaceList) {
        String controlModeType = "";
        for (ChipInterface chipInterface : chipInterfaceList) {
           List<String> resourceNameForImport = JSONArray.parseArray(chipInterface.getInterfaceTypesForImport()!=null?chipInterface.getInterfaceTypesForImport():"[]").toJavaList(String.class);
           if (resourceNameForImport.contains(configMasterChipPeripheralName)){
               controlModeType = chipInterface.getInterfaceType();
               break;
           }
        }
        return controlModeType;
    }

    /**
     * 将传入数据转换为系统可用的接口列表及控制模式信息
     * @param controlModeInterfaceName 控制模式类型名称
     * @param chipInterfaceList 芯片接口列表
     * @param configDataPinArray 配置数据中的引脚列表
     * @param driverLibraryId 驱动库Id
     * @param slaveChipId 被控芯片Id
     * @param masterChip 主控芯片
     *
     * @return 包含控制模式数据及接口配置数据的JSONObject
     */
    private JSONObject convertToInterfaceListAndControlMode(String controlModeInterfaceName, List<ChipInterface> chipInterfaceList, JSONArray configDataPinArray, Integer driverLibraryId, Integer slaveChipId, Chip masterChip) {
        JSONObject result = new JSONObject();

        Map<SFunction<ChipControlMode, ?>, Object> fieldValueMap = new HashMap<>();
        fieldValueMap.put(ChipControlMode::getDriverLibraryId, driverLibraryId);
        fieldValueMap.put(ChipControlMode::getChipId, slaveChipId);
        // 开始匹配控制模式的外设接口引脚
        JSONObject peripheralInterfaceData = new JSONObject();
        List<JSONObject> configDataPinList = configDataPinArray.toJavaList(JSONObject.class);
        List<ChipPin> matchedPinList = getMatchedPinList(masterChip.getChipId(), configDataPinList);
        if (matchedPinList.size() == configDataPinArray.size()) {
            Set<String> controlModeResourceNameSet = new HashSet<>();
            // 查询ChipPin取pin_names_for_import
            for (ChipPin chipPin : matchedPinList) {
                JSONArray pinNamesForImport = JSONArray.parseArray(chipPin.getPinNamesForImport() != null ? chipPin.getPinNamesForImport() : "[]");
                for (int i = 0; i < pinNamesForImport.size(); i++) {
                    String pinNameForImport = pinNamesForImport.getString(i);
                    for (JSONObject jsonObject : configDataPinList) {
                        // 如果pinNameForImport包含配置数据中的被控芯片接口名称，则认为匹配上
                        if (pinNameForImport.contains(jsonObject.getString("slaveChipInterfaceName"))) {
                            controlModeResourceNameSet.add(pinNameForImport.split("_")[0]);
                        }
                    }
                }
            }
            if (controlModeResourceNameSet.size() == 1) {
                // 若该名称包含控制模式类型名称，则认为匹配上
                String controlModeResourceName = controlModeResourceNameSet.iterator().next();
                if (controlModeResourceName.contains(controlModeInterfaceName)) {
                    peripheralInterfaceData.fluentPut("slaveChipInterfaceTypeName", controlModeInterfaceName);
                    peripheralInterfaceData.fluentPut("slaveChipInterfaceName", controlModeInterfaceName);
                    peripheralInterfaceData.fluentPut("masterChipResourceName", controlModeResourceName);
                    fieldValueMap.put(ChipControlMode::getName, "硬件" + controlModeInterfaceName);
                    // 校验硬件控制模式下 控制模式接口信息
                    List<ChipControlMode> chipControlModeList = chipControlModeService.findByProperties(fieldValueMap);
                    if (chipControlModeList.isEmpty()) {
                        // 未匹配上，使用默认的控制模式
                        fieldValueMap.put(ChipControlMode::getName, "软件" + controlModeInterfaceName);
                        LOGGER.error("找不到该硬件控制模式数据，请检查外设接口是否正确，已使用默认软件控制模式");
                    } else {
                        ChipControlMode chipControlModeResult = chipControlModeList.get(0);
                        List<ChipControlModeInterface> chipControlModeInterfaceListResult = chipControlModeInterfaceService.findByProperty(ChipControlModeInterface::getControlModeId, chipControlModeResult.getControlModeId());
                        ChipControlModeInterface chipControlModeInterface = chipControlModeInterfaceListResult.stream().filter(c -> controlModeInterfaceName.equals(c.getInterfaceName())).findFirst().orElse(null);
                        if (chipControlModeInterface == null){
                            // 未匹配上，使用默认的控制模式
                            fieldValueMap.put(ChipControlMode::getName, "软件" + controlModeInterfaceName);
                            LOGGER.error("控制模式接口无法匹配，已使用默认软件控制模式,请检查配置数据的外设信息是否正确");
                        }
                    }
                } else {
                    LOGGER.error("匹配到的控制模式接口资源与控制模式类型名称不匹配，匹配到的接口资源名称为:" + controlModeResourceName);
                    // 未匹配上，使用默认的控制模式
                    fieldValueMap.put(ChipControlMode::getName, "软件" + controlModeInterfaceName);
                }
            } else {
                LOGGER.error("匹配到多个控制模式接口资源，无法确认使用哪个接口资源，已使用默认软件控制模式,如需使用硬件请重新检查接口列表信息是否正确，匹配到的接口资源名称为:" + controlModeResourceNameSet.toString());
                fieldValueMap.put(ChipControlMode::getName, "软件" + controlModeInterfaceName);
            }
        } else {
            LOGGER.error("匹配到的引脚数量与配置数据中的引脚数量不一致，匹配到的引脚数量为:" + matchedPinList.size() + "，已使用默认软件控制模式,如需使用硬件请重新检查接口列表信息是否正确,配置数据中的引脚数量为:" + configDataPinArray.size() + ",请检查配置数据中的引脚是否正确");
            fieldValueMap.put(ChipControlMode::getName, "软件" + controlModeInterfaceName);
        }
        // 转换引脚列表为系统可用的接口列表类型
        List<JSONObject> interfaceList = new ArrayList<>();
        for (JSONObject oneConfigChipPin : configDataPinList) {
            for (ChipInterface chipInterface : chipInterfaceList) {
                JSONArray resourceNameForImport = JSONArray.parseArray(chipInterface.getResourceNamesForImport() != null ? chipInterface.getResourceNamesForImport() : "[]");
                if (resourceNameForImport.contains(oneConfigChipPin.getString("masterChipResourceName"))) {
                    JSONObject interfaceData = JSON.parseObject(JSON.toJSONString(oneConfigChipPin));
                    interfaceData.fluentPut("masterChipResourceName", chipInterface.getResourceName());
                    interfaceList.add(interfaceData);
                }
            }
        }
        // 加上外设接口
        if (!peripheralInterfaceData.isEmpty()) {
            interfaceList.add(peripheralInterfaceData);
        }
        List<ChipControlMode> chipControlModeList = chipControlModeService.findByProperties(fieldValueMap);
        if (!chipControlModeList.isEmpty()) {
            ChipControlMode chipControlModeResult = chipControlModeList.get(0);
            result.fluentPut("chipControlModeResult", chipControlModeResult);
            List<ChipControlModeInterface> chipControlModeInterfaceListResult = chipControlModeInterfaceService.findByProperty(ChipControlModeInterface::getControlModeId, chipControlModeResult.getControlModeId());
            List<Integer> chipControlModeInterfaceIdListResult = chipControlModeInterfaceListResult.stream().map(ChipControlModeInterface::getControlModeInterfaceId).collect(Collectors.toList());
            List<ChipControlModeInterfaceType> chipControlModeInterfaceTypeList = chipControlModeInterfaceTypeService.getList(chipControlModeInterfaceIdListResult);
            List<ProjectSlaveChipConfigInterface> addProjectSlaveChipConfigInterfaceList = new ArrayList<>();
            // 处理接口被控芯片的接口名称前缀问题
            for (int i = 0; i < interfaceList.size(); i++) {
                JSONObject interfaceData = interfaceList.get(i);
                String slaveChipInterfaceName = interfaceData.getString("slaveChipInterfaceName");
                for (int chipInterfaceIndex = 0; chipInterfaceIndex < chipControlModeInterfaceListResult.size(); chipInterfaceIndex++) {
                    ChipControlModeInterface chipControlModeInterface = chipControlModeInterfaceListResult.get(chipInterfaceIndex);
                    // 处理接口名称前缀问题：电路生成模块传入SPI_SCLK ，只匹配SCLK
                    if (slaveChipInterfaceName.contains(chipControlModeInterface.getInterfaceName())) {
                        interfaceData.fluentPut("slaveChipInterfaceName", chipControlModeInterface.getInterfaceName());
                        break;
                    }
                }
            }
            // 初始化接口配置数据
            for (int i = 0; i < chipControlModeInterfaceListResult.size(); i++) {
                ChipControlModeInterface chipControlModeInterface = chipControlModeInterfaceListResult.get(i);
                ProjectSlaveChipConfigInterface addProjectSlaveChipConfigInterface = new ProjectSlaveChipConfigInterface();
                addProjectSlaveChipConfigInterface.setSlaveChipInterfaceName(chipControlModeInterface.getInterfaceName());
                addProjectSlaveChipConfigInterface.setSlaveChipControlModeInterfaceId(chipControlModeInterface.getControlModeInterfaceId());
                addProjectSlaveChipConfigInterface.setSlaveChipInterfaceDescription(chipControlModeInterface.getInterfaceDescription());
                List<ChipControlModeInterfaceType> chipControlModeInterfaceTypeListByInterfaceId = chipControlModeInterfaceTypeList.stream().filter(c -> chipControlModeInterface.getControlModeInterfaceId().equals(c.getControlModeInterfaceId())).collect(Collectors.toList());
                List<String> interfaceTypeList = chipControlModeInterfaceTypeListByInterfaceId.stream().map(ChipControlModeInterfaceType::getInterfaceType).collect(Collectors.toList());
                String slaveChipInterfaceType = String.join(",", interfaceTypeList);
                addProjectSlaveChipConfigInterface.setSlaveChipInterfaceType(slaveChipInterfaceType);
                if (addProjectSlaveChipConfigInterface.getSlaveChipInterfaceName() != null) {
                    for (ChipControlModeInterfaceType chipControlModeInterfaceType : chipControlModeInterfaceTypeListByInterfaceId) {
                        if (addProjectSlaveChipConfigInterface.getSlaveChipInterfaceName().equals(chipControlModeInterfaceType.getInterfaceType())) {
                            addProjectSlaveChipConfigInterface.setSlaveChipInterfaceTypeId(chipControlModeInterfaceType.getId());
                        }
                    }
                }
                // 匹配接口对应的芯片接口,即将接口列表信息载入接口配置数据中
                for (int interfaceIndex = 0; interfaceIndex < interfaceList.size(); interfaceIndex++) {
                    JSONObject interfaceData = interfaceList.get(interfaceIndex);
                    if (chipControlModeInterface.getInterfaceName().equals(interfaceData.getString("slaveChipInterfaceName"))) {
                        JsonConverter<ProjectSlaveChipConfigInterface> projectSlaveChipConfigInterfaceJsonConverter = new JsonConverter<>();
                        addProjectSlaveChipConfigInterface = projectSlaveChipConfigInterfaceJsonConverter.convert(interfaceData, addProjectSlaveChipConfigInterface);
                        ChipInterface chipInterface = null;
                        if (StringUtils.isNotBlank(interfaceData.getString("masterChipResourceName"))) {
                            String masterChipResourceName = interfaceData.getString("masterChipResourceName");
                            Chip finalMasterChip = masterChip;
                            chipInterface = chipInterfaceList.stream().filter(c -> finalMasterChip.getChipId().equals(c.getChipId()) && masterChipResourceName.equals(c.getResourceName())).findFirst().orElse(null);
                        }
                        if (chipInterface != null) {
                            addProjectSlaveChipConfigInterface.setMasterChipInterfaceId(chipInterface.getInterfaceId());
                        } else {
                            LOGGER.error("该芯片接口找不到对应的芯片接口数据，请检查芯片接口是否正确，当前芯片接口为:" + interfaceData.toJSONString());
                        }
                    }
                }
                addProjectSlaveChipConfigInterfaceList.add(addProjectSlaveChipConfigInterface);
            }
            result.fluentPut("addProjectSlaveChipConfigInterfaceList", addProjectSlaveChipConfigInterfaceList);
        } else {
            LOGGER.error("该驱动模式找不到对应的控制模式数据，请检查驱动库是否正确，当前控制模式为:" + controlModeInterfaceName);
        }
        return result;
    }

    /**
     * 基于主控芯片和配置数据，转换masterChipResourceName为系统中的resource_name(基于芯片定义文件的resource_names_for_import和传入参数的masterChipResourceName查找)，
     * 并获取匹配的pin列表(芯片定义文件的pin_symbol和传入参数的masterChipResourceName一致，即认为匹配上)
     * @param masterChipId 主控芯片ID
     * @param configPinList 配置数据中的pin列表
     * @return JSON对象,包含
     * renameMasterChipResourceNameConfigPinList:转换masterChipResourceName后的pin ,matchedPinList:匹配的pin列表
     */
    private List<ChipPin> getMatchedPinList(Integer masterChipId, List<JSONObject> configPinList) {
        Map<String,ChipPin> chipPinMap = chipPinService.findByProperty(ChipPin::getChipId,masterChipId).stream().collect(Collectors.toMap(ChipPin::getPinSymbol,chipPin -> chipPin));
        List<ChipPin> matchedPinList = new ArrayList<>();
        for (JSONObject jsonObject : configPinList) {
            String thisPinMasterChipResourceName = jsonObject.getString("masterChipResourceName");
            String interfaceName = jsonObject.getString("slaveChipInterfaceName")!=null?jsonObject.getString("slaveChipInterfaceName"):"";
            if (thisPinMasterChipResourceName != null && chipPinMap.containsKey(thisPinMasterChipResourceName)) {
                ChipPin chipPin = chipPinMap.get(thisPinMasterChipResourceName);
                String pinNamesForImport = chipPin.getPinNamesForImport()!=null?chipPin.getPinNamesForImport():"";
                // 因为masterChipResourceName可能会重复,但是这个资源名称支持的接口名称不会一致,所以对接口名称进行校验(pinNamesForImport中包含了支持的硬件控制接口,格式为:控制模式号_接口名称,未包含该接口名称则认为该接口无法使用此引脚资源进行硬件控制模式)
                if (StringUtils.isNotBlank(pinNamesForImport) && pinNamesForImport.contains(interfaceName)){
                    matchedPinList.add(chipPin);
                }
            }
        }
        return matchedPinList;
    }

    /**
     * 更新项目
     * @param data
     * @return
     */
    public JSONObject updateProject(JSONObject data){
        Integer mainUserId = data.getInteger("mainUserId");
        Integer projectId = data.getInteger("projectId");
        String projectName = data.getString("projectName");
        String projectDescription = data.getString("projectDescription");
        if(mainUserId == null){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"mainUserId不能为空");
        }
        if(projectId == null){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"projectId不能为空");
        }
        Project project = projectService.findById(projectId);
        if(project == null){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"找不到对应的项目");
        }
        project.setUpdateUserId(mainUserId);
        project.setProjectId(projectId);
        if(StringUtils.isNotBlank(projectName)){
            project.setName(projectName);
        }
        if(StringUtils.isNotBlank(projectDescription)){
            project.setDescription(projectDescription);
        }
        projectService.updateById(project);
        return JsonUtil.getSuccess("更新成功").fluentPut(APP.DATA,packageInitData(project));
    }

    /**
     * 初始化项目
     * @param data
     * @return
     */
    public JSONObject initProject(JSONObject data){
        Integer projectId = data.getInteger("projectId");
        if(projectId == null){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"projectId不能为空");
        }
        Project project = projectService.findById(projectId);
        if(project == null){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"找不到对应的项目");
        }
        return JsonUtil.getSuccess("获取成功").fluentPut(APP.DATA,packageInitData(project));
    }

    /**
     * 组装初始化数据
     * @param project
     * @return
     */
    public JSONObject packageInitData(Project project){
        JSONObject data = new JSONObject();
        data.fluentPut("projectId",project.getProjectId())
                .fluentPut("mainEngineeringId",project.getMainEngineeringId())
                .fluentPut("projectName",project.getName() == null ? "" : project.getName())
                .fluentPut("projectDescription",project.getDescription() == null ? "" : project.getDescription())
                .fluentPut("createTime",project.getCreateTime())
                .fluentPut("creatorId",project.getCreatorId())
                .fluentPut("updateTime",project.getUpdateTime())
                .fluentPut("updateUserId",project.getUpdateUserId());
        return data;
    }

    /**
     * 删除项目
     * @param data
     * @return
     */
    public JSONObject deleteProject(JSONObject data){
        return projectService.delete(data);
    }

    /**
     * 查询芯片列表获取芯片ID 芯片型号 芯片厂家，并检查适配标识进行匹配
     *
     * @Author Liuqi
     * &Date 2023/08/18
     */
    public JSONObject getChipSupportMatrix() {
        List<Chip> chipList = chipService.findAll();
        //根据芯片类型枚举ChipTypeEnum.MASTER.getType()获取芯片类型
        List<Chip> masterChipList = chipList.stream().filter(chip -> chip.getType().equals(ChipTypeEnum.MASTER.getType())).collect(Collectors.toList());
        List<Chip> slaveChipList = chipList.stream().filter(chip -> chip.getType().equals(ChipTypeEnum.SLAVE.getType())).collect(Collectors.toList());
        //被控芯片根据芯片ID去驱动程序库中查询适配范围compatible存入适配标识(compatible)中
        List<DriverLibrary> driverLibraryList = driverLibraryService.findAll();
        slaveChipList.forEach(slaveChip -> {
            driverLibraryList.forEach(driverLibrary -> {
                if (slaveChip.getChipId().equals(driverLibrary.getChipId())) {
                    //如果适配标识为空,则直接赋值
                    if (slaveChip.getCompatible() == null) {
                        slaveChip.setCompatible(driverLibrary.getCompatible());
                    } else {
                        slaveChip.setCompatible(slaveChip.getCompatible() + "," + driverLibrary.getCompatible());
                    }
                }
            });
        });
        //将芯片信息存入chipInfoList中
        List<JSONObject> chipInfoList = new ArrayList<>();
        chipList.forEach(chip -> {
            JSONObject chipInfo = new JSONObject();
            chipInfo.fluentPut("chipId", chip.getChipId())
                    .fluentPut("model", chip.getModel())
                    .fluentPut("manufacturer", chip.getManufacturer());
            chipInfoList.add(chipInfo);
        });
        //以主控芯片为基准,匹配被控芯片的适配标识,将匹配结果存入chipMatrixList中
        List<JSONObject> chipMatrixList = new ArrayList<>();
        masterChipList.forEach(masterChip -> {
            JSONObject chipMatrix = new JSONObject();
            chipMatrix.fluentPut("masterChipId", masterChip.getChipId());
            List<Integer> supportSlaveChipID = new ArrayList<>();
            List<Integer> unSupportSlaveChipID = new ArrayList<>();
            slaveChipList.forEach(slaveChip -> {
                if (slaveChip.getCompatible() == null) {
                    unSupportSlaveChipID.add(slaveChip.getChipId());
                    return;
                }
                if (slaveChip.getCompatible().contains(masterChip.getCompatible())) {
                    supportSlaveChipID.add(slaveChip.getChipId());
                    //已经兼容的芯片不再进行匹配
                    return;
                }
                //如果被控芯片的适配标识不包含主控芯片的适配标识,则将被控芯片的ID存入unSupportSlaveChipID中
                unSupportSlaveChipID.add(slaveChip.getChipId());
            });
            chipMatrix.fluentPut("supportSlaveChipId", supportSlaveChipID);
            chipMatrix.fluentPut("unSupportSlaveChipId", unSupportSlaveChipID);
            chipMatrixList.add(chipMatrix);
        });
        //将芯片信息chipInfoList和芯片匹配结果chipMatrixList存入data中
        JSONObject data = new JSONObject();
        data.fluentPut("chipInfoList", chipInfoList)
                .fluentPut("chipDriverMatrix", chipMatrixList);
        return JsonUtil.getSuccess("").fluentPut(APP.DATA, data);
    }
}
